// 观察者模式：定义一对多的依赖关系，被观测者发生变化，观察者都会立即执行响应。
// Promise是基于观察者模式实现的，then方法用于添加函数到观察者数组中。
// Promise同时还是个Task函子
class Prom {
  static #PENDING = "pending";
  static #RESOLVED = "resolved";
  static #REJECTED = "rejected";

  constructor(exec) {
    this.status = Prom.#PENDING;
    this.value = null;
    this.reason = null;
    this.resolvedQueue = []; // 成功观察者
    this.rejectedQueue = []; // 失败观察者

    const resolve = (value) => {
      if (this.status === Prom.#PENDING) {
        this.value = value;
        this.status = Prom.#RESOLVED;
        this.resolvedQueue.forEach((cb) => cb(this.value));
      }
    };
    const reject = (reason) => {
      if (this.status === Prom.#PENDING) {
        this.reason = reason;
        this.status = Prom.#REJECTED;
        this.rejectedQueue.forEach((cb) => cb(this.reason));
      }
    };

    try {
      exec(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }

  then(onFulfilled, onRejected) {
    onFulfilled =
      typeof onFulfilled === "function" ? onFulfilled : (value) => value;
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (reason) => {
            throw reason;
          };

   return new Prom((resolve, reject) => {
      if (this.status === Prom.#RESOLVED) {
        queueMicrotask(() => {
          const x = onFulfilled(this.value);
          resolve(x);
        });
      }
      if (this.status === Prom.#REJECTED) {
        queueMicrotask(() => {
          const x = onRejected(this.reason);
          reject && reject(x);
        });
      }
      if (this.status === Prom.#PENDING) {
        this.resolvedQueue.push((value) => {
          queueMicrotask(() => {
            const x = onFulfilled(value);
            resolve(x);
          });
        });
        this.rejectedQueue.push((reason) => {
          queueMicrotask(() => {
            const x = onRejected(reason);
            reject && reject(x);
          });
        });
      }
    });
  }
}
